# -*- coding: utf-8 -*-
# 引用 SDK

import wave
import time
import threading
import pyaudio
import io
from common import credential
from tts import flowing_speech_synthesizer
from common.log import logger
from common.utils import is_python3

APPID = 1385122962 # 腾讯云账号 APPID，需要替换为您自己的 APPID
SECRET_ID = 'AKID43rTxHQNgojRvDIBrKZcS5Vk5vzu45uW' # 腾讯云账号 SecretID，需要替换为您自己的 SecretID
SECRET_KEY = 'TjpjS0MUQ9VeaMxLWVHrGSSEuX2trjQw' # 腾讯云账号 SecretKey，需要替换为您自己的 SecretKey

VOICETYPE = 200000000 # 音色类型
FASTVOICETYPE = "WCHN-2a7315f320994188bca398aab500e3ad" # 快速合成音色ID, 可在声音复刻控制台查看获取
EMOTION="angry"
CODEC = "pcm" # 音频格式：pcm/mp3
SAMPLE_RATE = 16000 # 音频采样率：8000/16000
ENABLE_SUBTITLE = False


class MySpeechSynthesisListener(flowing_speech_synthesizer.FlowingSpeechSynthesisListener):
    
    def __init__(self, id, codec, sample_rate):
        self.start_time = time.time()
        self.id = id
        self.codec = codec.lower()
        self.sample_rate = sample_rate

        self.audio_file = ""
        self.audio_data = bytes()
        
        # 初始化pyaudio
        self.p = pyaudio.PyAudio()
        self.stream = None
        self.is_playing = False
        
        # 用于MP3解码（如果需要）
        try:
            import pydub
            self.pydub_available = True
        except ImportError:
            self.pydub_available = False
            logger.warning("pydub not available, MP3 playback may not work properly")
    
    def set_audio_file(self, filename):
        self.audio_file = filename

    def on_synthesis_start(self, session_id):
        '''
        session_id: 请求session id，类型字符串
        '''
        if is_python3():
            super().on_synthesis_start(session_id)
        else:
            super(MySpeechSynthesisListener, self).on_synthesis_start(session_id)
        
        # TODO 合成开始，添加业务逻辑
        if not self.audio_file:
            self.audio_file = "speech_synthesis_output." + self.codec
        self.audio_data = bytes()
        
        # 初始化音频流
        self._init_audio_stream()

    def _init_audio_stream(self):
        """初始化音频播放流"""
        if self.stream is not None:
            self.stream.stop_stream()
            self.stream.close()
            
        # 根据编码格式设置参数
        if self.codec == "pcm":
            format = pyaudio.paInt16
            channels = 1
            rate = self.sample_rate
        else:  # mp3或其他格式
            format = pyaudio.paInt16
            channels = 1
            rate = self.sample_rate
            
        try:
            self.stream = self.p.open(format=format,
                                    channels=channels,
                                    rate=rate,
                                    output=True)
            self.is_playing = True
        except Exception as e:
            logger.error(f"Failed to open audio stream: {e}")
            self.is_playing = False

    def _play_audio_data(self, audio_bytes):
        """播放音频数据"""
        if not self.is_playing or self.stream is None:
            return
            
        try:
            # 如果是MP3格式且pydub可用，先解码
            if self.codec == "mp3" and self.pydub_available:
                import pydub
                from pydub import AudioSegment
                
                # 将MP3数据转换为PCM
                audio_segment = AudioSegment.from_mp3(io.BytesIO(audio_bytes))
                pcm_data = audio_segment.raw_data
                self.stream.write(pcm_data)
            else:
                # 直接播放PCM数据
                self.stream.write(audio_bytes)
                
        except Exception as e:
            logger.error(f"Error playing audio: {e}")

    def on_synthesis_end(self):
        if is_python3():
            super().on_synthesis_end()
        else:
            super(MySpeechSynthesisListener, self).on_synthesis_end()

        # TODO 合成结束，添加业务逻辑
        logger.info("write audio file, path={}, size={}".format(
            self.audio_file, len(self.audio_data)
        ))
        
        # 停止音频流
        if self.stream is not None:
            self.stream.stop_stream()
            self.stream.close()
            self.stream = None
            self.is_playing = False
            
        # 保存文件（可选）
        if self.codec == "pcm":
           wav_fp = wave.open("speech_synthesis_output.wav", "wb")
           wav_fp.setnchannels(1)
           wav_fp.setsampwidth(2)
           wav_fp.setframerate(self.sample_rate)
           wav_fp.writeframes(self.audio_data)
           wav_fp.close()
        elif self.codec == "mp3":
            fp = open(self.audio_file, "wb")
            fp.write(self.audio_data)
            fp.close()
        else:
            logger.info("codec {}: sdk NOT implemented, please save the file yourself".format(
                self.codec
            ))

    def on_audio_result(self, audio_bytes):
        '''
        audio_bytes: 二进制音频，类型 bytes
        '''
        if is_python3():
            super().on_audio_result(audio_bytes)
        else:
            super(MySpeechSynthesisListener, self).on_audio_result(audio_bytes)
        # 实时播放音频
        self._play_audio_data(audio_bytes)
        
        # 同时保存音频数据（可选）
        self.audio_data += audio_bytes

    def on_text_result(self, response):
        '''
        response: 文本结果，类型 dict，如下
        字段名       类型         说明
        code        int         错误码（无需处理，FlowingSpeechSynthesizer中已解析，错误消息路由至 on_synthesis_fail）
        message     string      错误信息
        session_id  string      回显客户端传入的 session id
        request_id  string      请求 id，区分不同合成请求，一次 websocket 通信中，该字段相同
        message_id  string      消息 id，区分不同 websocket 消息
        final       bool        合成是否完成（无需处理，FlowingSpeechSynthesizer中已解析）
        result      Result      文本结果结构体

        Result 结构体
        字段名       类型                说明
        subtitles   array of Subtitle  时间戳数组
        
        Subtitle 结构体
        字段名       类型     说明
        Text        string  合成文本
        BeginTime   int     开始时间戳
        EndTime     int     结束时间戳
        BeginIndex  int     开始索引
        EndIndex    int     结束索引
        Phoneme     string  音素
        '''
        if is_python3():
            super().on_text_result(response)
        else:
            super(MySpeechSynthesisListener, self).on_text_result(response)

        # TODO 接收到文本数据，添加业务逻辑
        result = response["result"]
        subtitles = []
        if "subtitles" in result and len(result["subtitles"]) > 0:
            subtitles = result["subtitles"]

    def on_synthesis_fail(self, response):
        '''
        response: 文本结果，类型 dict，如下
        字段名 类型
        code        int         错误码
        message     string      错误信息
        '''
        if is_python3():
            super().on_synthesis_fail(response)
        else:
            super(MySpeechSynthesisListener, self).on_synthesis_fail(response)

        # TODO 合成失败，添加错误处理逻辑
        err_code = response["code"]
        err_msg = response["message"]
        
        # 停止音频流
        if self.stream is not None:
            self.stream.stop_stream()
            self.stream.close()
            self.stream = None
            self.is_playing = False

    def __del__(self):
        """清理资源"""
        if self.stream is not None:
            self.stream.stop_stream()
            self.stream.close()
        if self.p is not None:
            self.p.terminate()


def process(id):
    listener = MySpeechSynthesisListener(id, CODEC, SAMPLE_RATE)
    credential_var = credential.Credential(SECRET_ID, SECRET_KEY)
    synthesizer = flowing_speech_synthesizer.FlowingSpeechSynthesizer(
        APPID, credential_var, listener)
    synthesizer.set_voice_type(VOICETYPE)
    synthesizer.set_codec(CODEC)
    synthesizer.set_sample_rate(SAMPLE_RATE)
    synthesizer.set_enable_subtitle(ENABLE_SUBTITLE)
    synthesizer.set_fast_voice_type(FASTVOICETYPE)
    synthesizer.set_emotion_category(EMOTION)
   
    synthesizer.start()
    ready = synthesizer.wait_ready(5000)
    if not ready:
        logger.error("wait ready timeout")
        return
    
    texts = [
        "你这泼",
        "猴，十分无",
        "状。",
        "老是撞俺老猪，",
        "嘻嘻哈哈的，没个正经样儿！",
    ]

    while True:
        for text in texts:
            synthesizer.process(text)
        break
    synthesizer.complete() # 发送合成完毕指令

    synthesizer.wait() # 等待服务侧合成完成

    logger.info("process done")


def process_multithread(number):
    thread_list = []
    for i in range(0, number):
        thread = threading.Thread(target=process, args=(i,))
        thread_list.append(thread)
        thread.start()
        print(i)

    for thread in thread_list:
        thread.join()


if __name__ == "__main__":
    process_multithread(1)